#!/usr/local/bin/python
# coding:utf-8
import psutil, time
import sys
import os
from werkzeug.contrib.cache import SimpleCache
import commands
import requests
import json

cache = SimpleCache()


class Tmcontrol():
    requests_url = "http://monitor.tianma3600.com/monitor/serverlog/addServerlog"
    # 获取主机名称
    def hostname(self):
        sys = os.name
        if sys == 'nt':
            hostname = os.getenv('computername')
            return hostname
        elif sys == 'posix':
            host = os.popen('echo $HOSTNAME')
            try:
                hostname = host.read()
                return hostname
            finally:
                host.close()
        else:
            return 'Unkwon hostname'

    # 获取进程状态
    def processStatus(self, processName):
        pids = psutil.pids()  # 获取主机所有的PID
        a = 1
        for pid in pids:  # 对所有PID进行循环
            p = psutil.Process(pid)  # 实例化进程对象
            if p.name() == processName:  # 判断实例进程名与输入的进程名是否一致（判断进程是否存活）
                print (a)  # 返回1，进程存活
                a += 1
        if a == 1:
            print (0)  # 返回0，进程逝去
            return 0
        return 1

    # 获取进程PID
    def processPID(self, processName):
        pids = psutil.pids()
        for pid in pids:
            p = psutil.Process(pid)
            if p.name() == processName:
                return pid
                return True  # 如果找到该进程则打印它的PID，返回true
        else:
            print('找不到进程' + processName)
            return False  # 没有找到该进程，返回false

    # 获取进程的端口号
    def processPort(self, pid):
        p = psutil.Process(pid)
        data = p.connections()
        data_listen = [x for x in data if 'LISTEN' in x]
        # pid_port=[]
        # for port in data_listen:
        #     pid_port.append((port.laddr.port))
        # return list(set(pid_port))
        return list(data_listen[0][3])[1]

    def GetMemInfo(self):
        # 取内存信息
        mem = psutil.virtual_memory()
        memInfo = {'memTotal': int(mem.total / 1024 / 1024), 'memFree': int(mem.free / 1024 / 1024),
                   'memBuffers': int(mem.buffers / 1024 / 1024), 'memCached': int(mem.cached / 1024 / 1024)}
        memInfo['memRealUsed'] = memInfo['memTotal'] - memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached']
        return memInfo

    def GetLoadAverage(self):
        c = os.getloadavg()
        data = {};
        data['one'] = float(c[0]);
        data['five'] = float(c[1]);
        data['fifteen'] = float(c[2]);
        return data;

    def get_cpu_time(self):
        cpu_time = 0.00
        cpu_times = psutil.cpu_times()
        for s in cpu_times: cpu_time += s
        return cpu_time;

    def get_process_cpu_time(self):
        pids = psutil.pids()
        cpu_time = 0.00;
        for pid in pids:
            try:
                cpu_times = psutil.Process(pid).cpu_times()
                for s in cpu_times: cpu_time += s
            except:
                continue;
        return cpu_time;

    def get_cpu_percent(self):
        percent = 0.00;
        old_cpu_time = cache.get('tmold_cpu_time')
        old_process_time = cache.get('tmold_process_time')
        if not old_cpu_time:
            old_cpu_time = self.get_cpu_time()
            old_process_time = self.get_process_cpu_time()
            time.sleep(1)
        new_cpu_time = self.get_cpu_time()
        new_process_time = self.get_process_cpu_time()
        try:
            percent = round(100.00 * ((new_process_time - old_process_time) / (new_cpu_time - old_cpu_time)), 2)
        except:
            percent = 0.00
        cache.set('tmold_cpu_time', new_cpu_time)
        cache.set('tmold_process_time', new_process_time)
        if percent > 100: percent = 100
        if percent > 0: return percent;
        return 0.00;

    def GetCpuInfo(self, interval=1):
        time.sleep(0.5)
        # 取CPU信息
        cpuCount = psutil.cpu_count()
        used = self.get_cpu_percent()
        return used, cpuCount

    def GetNetWork(self):
        cache_timeout = 86400
        networkIo = psutil.net_io_counters()[:4]
        otime = cache.get("tmotime")
        if not otime:
            otime = time.time()
            cache.set('tmup', networkIo[0], cache_timeout)
            cache.set('tmdown', networkIo[1], cache_timeout)
            cache.set('tmotime', otime, cache_timeout)

        ntime = time.time();
        networkInfo = {}
        networkInfo['upTotal'] = networkIo[0]
        networkInfo['downTotal'] = networkIo[1]
        networkInfo['up'] = round(float(networkIo[0] - cache.get("tmup")) / 1024 / (ntime - otime), 2)
        networkInfo['down'] = round(float(networkIo[1] - cache.get("tmdown")) / 1024 / (ntime - otime), 2)
        networkInfo['downPackets'] = networkIo[3]
        networkInfo['upPackets'] = networkIo[2]

        cache.set('tmup', networkIo[0], cache_timeout)
        cache.set('tmdown', networkIo[1], cache_timeout)
        cache.set('tmotime', time.time(), cache_timeout)
        networkInfo['cpu'] = self.GetCpuInfo()
        networkInfo['load'] = self.GetLoadAverage();
        networkInfo['mem'] = self.GetMemInfo()
        networkInfo['nginx'] = self.processStatus('nginx') #1表示存活，0表示死掉
        if networkInfo['nginx']==0:
           networkInfo['nginx'] = self.processStatus('httpd') #1表示存活，0表示死掉
        networkInfo['mysql'] = self.processStatus('mysqld')  # 1表示存活，0表示死掉
        #print(networkInfo)
        return networkInfo
        # return networkInfo

    def GetDiskInfo(self):
        #取磁盘分区信息
        temp = commands.getstatusoutput("df -h -P|grep '/'|grep -v tmpfs")[1]
        print(temp)
        temp1 = temp.split('\n');
        #print(temp1)
        return temp1;

    def start(self):
        now_time = int(time.time())
        day_time = now_time - now_time % 86400 + time.timezone + 24 * 3600
        workInfo = self.GetNetWork()
        disk = self.GetDiskInfo()
        nginx_mysql_install = 0
        site_backup = 0
        database_backup = 0
        if sys.argv and len(sys.argv)>2 and sys.argv[1]!=None :
            nginx_mysql_install = int(sys.argv[1])
        if sys.argv and len(sys.argv)>3 and sys.argv[2]!=None :
            backup_path = sys.argv[2]
            print(backup_path)
            if now_time>(day_time+8*60*60) :
                file_time = time.strftime("%Y%m%d", time.localtime())
                if len(backup_path)>1 and (nginx_mysql_install==1 or nginx_mysql_install==3) :
                    site_backup = 2
                    site_file_names = os.listdir(backup_path+"/site/")
                    for file_name in site_file_names:
                        if file_name.find(file_time)!=None and file_name.find(file_time)>=0 :
                            site_backup = 1
                if len(backup_path)>1 and (nginx_mysql_install==2 or nginx_mysql_install==3) :
                    database_backup = 2
                    database_file_names = os.listdir(backup_path+"/database/")
                    for file_name in database_file_names:
                        if file_name.find(file_time)!=None and file_name.find(file_time)>=0 :
                            database_backup = 1
        #if now_time>day_time and now_time<(day_time+8*60*60):
        #    workInfo['load']['one'] = workInfo['load']['one']/2
        #    workInfo['load']['five'] = workInfo['load']['five'] / 2
        #    workInfo['load']['fifteen'] = workInfo['load']['fifteen'] / 2
        data = {
            "up": workInfo['up'],  #上行速度，预估
            "down": workInfo['down'],   #下行速度，预估
            "upTotal": workInfo['upTotal'],  #总共发送的流量，单位B
            "downTotal": workInfo['downTotal'],  #总共接收的流量，单位B
            "cpu_per": workInfo['cpu'][0],   #cpu使用情况，百分比，值为1表示百分之1
            "cpu_num": workInfo['cpu'][1],   #cpu核心数
            "memFree": workInfo['mem']['memFree'], #内存空闲量，单位兆
            "memTotal": workInfo['mem']['memTotal'],   #内存总量，单位兆
            "memCached": workInfo['mem']['memCached'],  #缓存内存使用量，单位兆
            "memBuffers": workInfo['mem']['memBuffers'],  #Buffers内存使用量，单位兆
            "memRealUsed": workInfo['mem']['memRealUsed'],  #内存真正使用量，单位兆
            "load_one": workInfo['load']['one']/workInfo['cpu'][1]/2,  #过去一分钟平局负载
            "load_five": workInfo['load']['five']/workInfo['cpu'][1]/2,  # 过去五分钟平局负载
            "load_fifteen": workInfo['load']['fifteen']/workInfo['cpu'][1]/2,  # 过去十五分钟平局负载
            "disk":json.dumps(disk),    #磁盘使用情况，是个json数组，"["/dev/vda1 40G 15G 23G 40% /", "/dev/vdb1 148G 99G 42G 71% /mnt"]"，自己解析，分别表示磁盘名、磁盘总大小、磁盘使用量、磁盘剩余量、磁盘使用百分比、磁盘挂载目录
            "nginx":workInfo['nginx'],   #nginx存活状态：1表示存活，0表示死掉
            "mysql": workInfo['mysql'],  # mysql存活状态：1表示存活，0表示死掉
            "nginx_mysql_install":nginx_mysql_install,  #nginx 和 mysql 安装状态  0两个都没安装，1 nginx安装，2 mysql安装，3两个都安装
            "site_backup": site_backup,
            "database_backup": database_backup
        }
        print(data)
        resData=requests.post(self.requests_url, data=data)  #发送一个post请求
        print(resData.content)

#计算cup相关参数时 设置了延迟再处理，所以本脚本执行时间会相对较长，大约两秒
if __name__ == "__main__":
    tmcontrol = Tmcontrol()
    #tmcontrol.processStatus('mysqld')
    tmcontrol.start()
